/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2020-2021.
 * Description: watchdog header file
 * Author: yanbo <joey.yanbo@huawei.com>
 * Create: 2020-11-19
 */
#ifndef WATCHDOG_H
#define WATCHDOG_H

#include <linux/hal/drol.h>
#include <linux/notifier.h>
#define bsp_reset_wdt			call_hwdog_handle
#define bsp_reset_wdt_nolock		call_hwdog_handle_nolock
#define get_wdt_time			hwdog_get_final_feed_time
#define inner_wdt_notify_register	register_hwdog_notify
#define inner_wdt_notify_unregister	unregister_hwdog_notify
#define wdt_notify_register		register_softdog_notify
#define wdt_notify_unregister		unregister_softdog_notify

typedef void (*wtd_notify_t)(void);
struct wdt_notify {
	struct list_head entry;
	wtd_notify_t func;
};

typedef int (*feed_handle_t)(void);
#ifdef CONFIG_HISI_WATCHDOG
enum watchdog_cmd {
	CMD_EXTEND_TIME_HWDOG = 0x1,
	CMD_RESET_TIME_HWDOG = 0x2,
	CMD_STOP_ALL = 0x3,
	CMD_SET_TIME_HWDOG = 0x4,
	CMD_FEED_HWDOG = 0x5,
	CMD_SET_INTERVAL_HWDOG = 0x6,
	CMD_SET_INERTVAL_SOFTDOG = 0x7,
	CMD_STOP_SOFTDOG = 0x8,
	CMD_FEED_SOFTDOG = 0x9,
	CMD_SET_SEC_TIME_HWDOG = 0xa,
};

extern void hwdog_simple_init(const void *dtb_addr, bool use_fdt, drol_map map, drol_unmap unmap);
extern void hwdog_early_init(void);
extern void hwdog_late_init(void);
extern void hwdog_feed(void);
extern void hwdog_feed_intermittent(int interval);
extern unsigned long long hwdog_get_final_feed_time(void);
extern int register_hwdog_handle(feed_handle_t handle);
extern int unregister_hwdog_handle(void);
extern void call_hwdog_handle_nolock(void);
extern void call_hwdog_handle(void);
extern void call_hwdog_handle_special(void);
extern void hwdog_stop(void);
extern void hwdog_set_feed_count(unsigned int cnt);
extern void hwdog_extend_feed_max(unsigned int min);
extern void hwdog_set_feed_max(unsigned int min);
extern void hwdog_set_sec_feed_max(unsigned int sec);
extern void hwdog_reset_feed_max(void);
extern void hwdog_set_interval(unsigned int interval);
extern int register_hwdog_notify(wtd_notify_t func);
extern int unregister_hwdog_notify(wtd_notify_t func);
extern int register_hwdog_final_notify(wtd_notify_t func);
extern int unregister_hwdog_final_notify(void);
extern void call_hwdog_notify(void);
extern void wdt_notify_init(void);
extern int register_softdog_notify(wtd_notify_t func);
extern int unregister_softdog_notify(wtd_notify_t func);
extern int register_softdog_final_notify(wtd_notify_t func);
extern int unregister_softdog_final_notify(void);
extern void call_softdog_notify(void);
extern void softdog_set_interval(unsigned int sec);
extern void softdog_stop(void);
extern void softdog_init(void);
extern void wtd_proc_init(void);
extern void hwdog_cpy_op(struct drol_op *op_addr, int *op_size_addr);
extern int softdog_kthread_create(void);
extern struct drol_op wacthdog_kexec_op;
extern int wacthdog_kexec_op_size;
extern void rtos_wdt_stop(void);
extern int rtos_wtd_write(enum watchdog_cmd cmd, unsigned int value);
extern int get_softdog_feed_stat(unsigned long long *timeout_feed, unsigned long long *cur_feed);
extern void hwdog_feed_in_pfnwalk(unsigned long start_pfn, unsigned long pfn);
extern int rtos_softdog_exceed_pre_notifier_register(struct notifier_block *nb);
extern int rtos_softdog_exceed_pre_notifier_unregister(struct notifier_block *nb);
#ifdef CONFIG_RTOS_HAL_SELFDECOMPRESS_MAP_PHYS_ADDR_ABOVE_4G
extern void unmap_hwdog_addr_above_4G(void *virt);
#endif
#else
static inline void hwdog_simple_init(const void *dtb_addr, bool use_fdt, drol_map map, drol_unmap unmap) {}
static inline void hwdog_feed(void) {}
static inline void hwdog_feed_intermittent(int interval) {}
static inline unsigned long long hwdog_get_final_feed_time(void)
{
	return 0;
}
static inline int register_hwdog_handle(feed_handle_t handle)
{
	return 0;
}
static inline int unregister_hwdog_handle(void)
{
	return 0;
}
static inline void call_hwdog_handle_nolock(void) {}
static inline void call_hwdog_handle(void) {}
static inline void call_hwdog_handle_special(void) {}
static inline void hwdog_stop(void) {}
static inline int register_hwdog_notify(wtd_notify_t func)
{
	return 0;
}
static inline int unregister_hwdog_notify(wtd_notify_t func)
{
	return 0;
}
static inline int register_hwdog_final_notify(wtd_notify_t func)
{
	return 0;
}
static inline int unregister_hwdog_final_notify(void)
{
	return 0;
}
static inline int register_softdog_notify(wtd_notify_t func)
{
	return 0;
}
static inline int unregister_softdog_notify(wtd_notify_t func)
{
	return 0;
}
static inline int register_softdog_final_notify(wtd_notify_t func)
{
	return 0;
}
static inline int unregister_softdog_final_notify(void)
{
	return 0;
}
static inline void hwdog_cpy_op(struct drol_op *op_addr, int *op_size_addr) {}
static inline int softdog_kthread_create(void)
{
	return -EPERM;
}
static inline void hwdog_feed_in_pfnwalk(unsigned long start_pfn, unsigned long pfn) {}
#endif

#endif
